﻿using FaceWebServer.Utility.Model;
using FaceWebServer.Utility.VerifyAttribute;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FaceWebServer.Utility.FilterAttribute
{
    /// <summary>
    /// 参数验证过滤器
    /// </summary>
    public class VerifyActionFilterAttribute : Attribute, IActionFilter
    {
        private ILogger<VerifyActionFilterAttribute> _logger = null;

        public VerifyActionFilterAttribute(ILogger<VerifyActionFilterAttribute> logger)
        {
            this._logger = logger;
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            //this?._logger.LogDebug($"{context.HttpContext.Request.Path} ActionFilter 执行后!");
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {

            if (context.ActionArguments.Count > 0)
            {
                var Parameters = context.ActionDescriptor.Parameters;
                var parDic = new Dictionary<string, ParameterDescriptor>();
                foreach (var parDtl in Parameters)
                {
                    parDic.Add(parDtl.Name, parDtl);
                }

                foreach (var ArgumentItem in context.ActionArguments)
                {

                    object parValue = ArgumentItem.Value;
                    var parDtl = parDic[ArgumentItem.Key];
                    Type parType = parDtl.ParameterType;
                    //var parInfo= parDtl.ParameterInfo;
                   
                    if (parType.IsClass)
                    {
                        if (!VerifyEntity(parType, parValue, r => context.Result = r)) return;
                    }
                }

            }


            this?._logger.LogDebug($"{context.HttpContext.Request.Path} ActionFilter 执行前!");
        }

        public static bool VerifyEntity(Type parType, object parValue, Action<IActionResult> VerifyErrorCallblack)
        {
            foreach (var parFiled in parType.GetProperties())
            {
                if (parFiled.IsDefined(typeof(AbstractVerifyAttribute), true))
                {
                    var attrs = parFiled.GetCustomAttributes(typeof(AbstractVerifyAttribute), true);
                    foreach (var objAttr in attrs)
                    {
                        AbstractVerifyAttribute attr = objAttr as AbstractVerifyAttribute;
                        object pValue = parFiled.GetValue(parValue);
                        if (!attr.Verify(ref pValue))
                        {
                            
                            //给Result 赋值，可以直接阻断Action执行
                            //var result = new JsonResultModel(attr.ErrorCode, $"Filed [{parFiled.Name}] verify error");
                            var result = new JsonResultModel(attr.ErrorCode, attr.ErrorDescription);

                            VerifyErrorCallblack(new JsonResult(result));
                            return false;
                        }else
                        {
                            parFiled.SetValue(parValue, pValue);
                        }
                    }
                }
            }
            return true;
        }
    }
}
